package com.kaili.zuul.security;

import com.alibaba.fastjson.JSONObject;
import com.kaili.common.entity.LoginDetail;
import com.kaili.common.response.CommonStatus;
import com.kaili.common.response.ResponseData;
import com.kaili.common.util.HexStringUtils;
import com.kaili.common.util.SHA256Util;
import com.kaili.zuul.service.LoginService;
import com.kaili.zuul.utils.RequestParamUtils;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.Random;

/**
 * Created by rzh on 18-5-4.
 */
@Configuration
public class Provider implements AuthenticationProvider {

    @Autowired
    LoginService loginService;
    @Autowired
    protected HttpServletResponse response;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String username = authentication.getName();
        if (username == null || username.equals("")){
            //post请求上边的方法获取不到用户名,所以采用流的方式获取
            String requestJson = RequestParamUtils.getRequestParam(httpServletRequest);
            JSONObject jsonObject = JSONObject.parseObject(requestJson);
            username = (String) jsonObject.get("username");
        }
        byte[] bytes = Base64.decodeBase64((String)authentication.getCredentials());
        String password = "123456";
//        try {
//            String result = new String(bytes, "UTF-8");
//            String[] s = result.split(";");
//            BigInteger p = new BigInteger(s[1]);
//            BigInteger y = new BigInteger(s[2]);
//            BigInteger x = new BigInteger(loginService.getVerifyCode(s[3]));
//            String k = y.modPow(x, p).toString();
//            password = s[0].substring(0, s[0].length() - k.length());
//        } catch (UnsupportedEncodingException e) {
//            return null;
//        }
//        String code = ((Calendar)authentication.getDetails()).getCode();//公司编码(此处切换数据源)
//        String type = ((Calendar)authentication.getDetails()).getType();//0系统1PDA2其他

        String code = httpServletRequest.getHeader("code");//公司编码(此处切换数据源)
        if (code == null || code.equals("")){
            code = "99999";
        }
        String type = httpServletRequest.getHeader("type");////0系统1PDA2其他
        String language = httpServletRequest.getHeader("language");//获取语言类型
        String imageCode = httpServletRequest.getHeader("imageCode");
        String key = httpServletRequest.getHeader("key");
        httpServletRequest.getSession().setAttribute("companyId",code);
        httpServletRequest.getSession().setAttribute("language",language);
        httpServletRequest.setAttribute("username", username);
        LoginDetail loginDetail;
        try {
            if("1".equals(type)){
                loginDetail = loginService.loadEmployeeByUsername(username);
            }else{
                loginDetail = loginService.loadUserByUsername(username);
                String validationCode = loginService.systemParmeterConfig("TRUN_ON_VALIDATION_CODE");
                if (false) {
                    response.setContentType("application/json;charset=utf-8");
                    PrintWriter out = response.getWriter();
                    String s ;
                    String value = loginService.getVerifyCode(key);
                    if (!imageCode.equalsIgnoreCase(value)) {
                        s = JSONObject.toJSONString(new ResponseData(JSONObject.toJSON("验证码错误!"), CommonStatus.CONTINUE));
                        out.write(s);
                        out.flush();
                        out.close();
                    }
                }
            }
            loginDetail.setCode(code);
            loginDetail.setType(type);
            if(loginDetail != null) {
                String count = loginService.systemParmeterConfig("Logon_Error_Limit_Number");
                httpServletRequest.setAttribute("count", count);
                if (loginDetail.getUnlock() != null) {
                    if (loginDetail.getUnlock() == 1) {
                        httpServletRequest.setAttribute("unlock", "1");
                        httpServletRequest.getAttribute("unlock");
                        System.out.println(httpServletRequest.getAttribute("unlock"));
                        System.out.println(httpServletRequest.getAttribute("unlock"));
                        return null;
                    }
                }
                String decode = HexStringUtils.fromHex(loginDetail.getPassword());//还原16进的密码
                String hashd = decode.substring(0, decode.length() - 64);//去掉后面64位hash算法
                String hashe = hashd.substring(hashd.length() - 3, hashd.length());//截取后3位 随机次数
                System.out.println(hashd);
                System.out.println(hashe);
                String salt = hashd.substring(2, 8);//保留salt
                System.out.println(salt);
                int cycletimes = Integer.parseInt(hashe);
                String hexpwd = hexpwd(password, password, salt, cycletimes);//加密后的密码
                if (hexpwd.equalsIgnoreCase(loginDetail.getPassword())) {
                    return new UsernamePasswordAuthenticationToken(loginDetail, password, loginDetail.getAuthorities());
                } else {
                    Integer countTrans = loginService.getTranslate(username + code);
                    if (countTrans == null) {
                        countTrans = 0;
                    }
                    httpServletRequest.setAttribute("code", code);
                    loginService.saveTranslate(username + code, countTrans + 1);
                    System.out.println(countTrans);
                    return null;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass));
    }

    public String hexpwd(String pwd, String npwd, String salt, int cycletimes) {
        System.out.println(SHA256Util.getSHA256StrJava("G1" + salt + pwd).length());
        Random random = new Random();
        String sh256 = "";
        sh256 = SHA256Util.getSHA256StrJava("G1" + salt + pwd);
        for (int i = 0; i <= cycletimes; i++) {
            sh256 = SHA256Util.getSHA256StrJava("G1" + salt + pwd + sh256);
            sh256 = sh256;
            ;
        }
        System.out.println(sh256);
        String hex = HexStringUtils.toHex("G1" + salt + cycletimes + sh256);//16进制字符串
        System.out.println("16进制字符串存数据库" + hex);
        return hex;
    }


}
